import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

import java.net.*;
import java.util.*;
import java.io.*;
import java.applet.*;
import javax.*;
import javax.imageio.ImageIO;
import javax.media.*;

public class Client extends JFrame implements ActionListener, ControllerListener
{
	private static InetAddress host = null;
	private static final int PORT = 1234;
	private static Socket socket;
	private static Scanner networkInput,keyboard;
	private static PrintWriter output;
	private static ObjectOutputStream objOutput;
	private static ObjectInputStream objInput;
	private static FileOutputStream fileOutput;

	public static ArrayList<Email> userEmail = new ArrayList<Email>();
	
	String userName, message, recipient, command, attachmentPath;
	int index = 1;
	
	private JTextField txtUserName;
	private JTextArea sendMessage, sendMessageName, chatLog;
	private JLabel lblFirstName = new JLabel("Enter your First Name");
	private JLabel lblSendMessage = new JLabel("Send a new message");
	private JLabel lblRecipient = new JLabel("Recipient:");
	private JLabel lblEnterMessage = new JLabel("Message:");
	private JLabel lblMedia = new JLabel("View Attachment Media Below :");
	private JButton btnLogin, btnLogout, btnReadMailbox, btnSendMessage, btnDelete, btnAttach, btnViewAttach;
	public JPanel pnlHeader, pnlButtons, pnlMailbox, pnlSend, pnlLeft, pnlRight, pnlButtonSend, pnlRecipient, pnlMessage;
	public static DefaultListModel emailData = new DefaultListModel();
	public JList mailbox = new JList(emailData);
	
	private JFileChooser fileChooser = new JFileChooser();
    private File file, sendFile, receiveFile;
	private Boolean sendWithAttachment = false;

	private AudioClip clip;
	private JButton play, stop, loop;
	
	////////////////////ATTACHMENT FRAME /////////////////////////////
	//private JTextField fileName;
	//private File file;
	private Player player;

	//private Player player;
	

	
	public static void main(String[] args) throws IOException
	{			
		Client frame = new Client();
		frame.setTitle("NSD Email Client");
		frame.pack();
		//frame.setSize(330,600);
		frame.setVisible(true);
		//frame.setResizable( false );		
		frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		try
		{
			host = InetAddress.getLocalHost();
			socket = new Socket(host, PORT);
			networkInput = new Scanner(socket.getInputStream());
			output = new PrintWriter(socket.getOutputStream(),true);
			objOutput = new ObjectOutputStream(socket.getOutputStream());
			objInput = new ObjectInputStream(socket.getInputStream());
			
		}
		catch(UnknownHostException uhEx)
		{
			JOptionPane.showMessageDialog(null, "Host ID not found");
			System.exit(1);
		}
		catch (IOException ioEx)
		{
			JOptionPane.showMessageDialog(null, "Please make sure server is running");
		}	
			
	}
	
	public Client()
	{		
		setLayout(new BorderLayout());
	
		/////////////////////START OF LEFT PANEL//////////////////////
		pnlLeft = new JPanel(new BorderLayout());				
		pnlLeft.setPreferredSize(new Dimension(330,700));
			
		pnlHeader = new JPanel();
		pnlButtons = new JPanel();
		pnlMailbox = new JPanel();
		pnlSend = new JPanel();
		pnlButtonSend = new JPanel(new BorderLayout());
		pnlRecipient = new JPanel(new BorderLayout());
		pnlMessage = new JPanel(new BorderLayout());
		
		pnlHeader.setPreferredSize(new Dimension(330,80));
		pnlSend.setPreferredSize(new Dimension(330, 200));
		
		txtUserName = new JTextField(10);
		
		btnLogin = new JButton("Login");
		btnLogin.addActionListener(this);
		
		btnLogout = new JButton("Logout");
		btnLogout.addActionListener(this);
		btnLogout.setEnabled(false);
		
		btnDelete = new JButton("Delete");
		btnDelete.addActionListener(this);
			
		sendMessageName = new JTextArea(2,20);
		sendMessageName.setWrapStyleWord(true);
		sendMessageName.setLineWrap(true);
		sendMessageName.setText("Enter Recipient");
		
		sendMessage = new JTextArea(5,20);
		sendMessage.setWrapStyleWord(true);
		sendMessage.setLineWrap(true);
		sendMessage.setText("Enter Message......");
		
		btnReadMailbox = new JButton("Read Mailbox");
		btnReadMailbox.addActionListener(this);
		btnReadMailbox.setEnabled(false);
		
		btnAttach = new JButton("Attatch File");
		btnAttach.addActionListener(this);
		btnAttach.setEnabled(false);
		
		btnSendMessage = new JButton("Send A Message");
		btnSendMessage.addActionListener(this);
		
		btnViewAttach = new JButton("View Attachment");
		btnViewAttach.addActionListener(this);
		
		pnlHeader.add(lblFirstName);
		pnlHeader.add(txtUserName);		
		
		pnlHeader.add(btnLogin);
		pnlHeader.add(btnLogout);
		pnlHeader.add(btnReadMailbox);
		
		JScrollPane scrollMail = new JScrollPane(mailbox);
		scrollMail.setPreferredSize(new Dimension(320,375));
		pnlMailbox.add(new JScrollPane(scrollMail));
		pnlMailbox.add(btnViewAttach);
		
		pnlSend.add(lblSendMessage);
		//pnlSend.add(lblRecipient);
		
		//pnlSend.add(sendMessageName);
		//pnlSend.add(lblEnterMessage);
		//pnlSend.add(new JScrollPane(sendMessage));
		
		pnlRecipient.add(lblRecipient,BorderLayout.WEST);
		pnlRecipient.add(sendMessageName,BorderLayout.EAST);
		
		pnlMessage.add(lblEnterMessage,BorderLayout.WEST);
		pnlMessage.add(new JScrollPane(sendMessage),BorderLayout.EAST);
		
		pnlButtonSend.add(btnAttach, BorderLayout.NORTH);
		pnlButtonSend.add(btnSendMessage, BorderLayout.SOUTH);
		
		pnlSend.add(pnlRecipient);
		pnlSend.add(pnlMessage);
		pnlSend.add(pnlButtonSend);
		
		pnlLeft.add(pnlHeader, BorderLayout.NORTH);
		pnlLeft.add(pnlMailbox, BorderLayout.CENTER);
		pnlLeft.add(pnlSend, BorderLayout.SOUTH);	
		
		////////////////////////END OF LEFT PANEL////////////////////////
		
		////////////////////////START OF RIGHT PANEL/////////////////////////
		pnlRight = new JPanel(new BorderLayout());
		pnlRight.setPreferredSize(new Dimension(330,600));
		
		pnlRight.add(lblMedia);
		
		////////////////////////END OF RIGHT PANEL/////////////////////////
		
		
		add(pnlLeft, BorderLayout.WEST);
		//add(pnlRight,BorderLayout.EAST);
		
	}
	
	public void sendMessage()
	{
		recipient = sendMessageName.getText();
		message = sendMessage.getText();
		command = "newMessage";
		int index = 0;
		
		Email email = new Email(recipient, userName, message, "newMessage","none", null, "none");  //command);
		
		try
		{
			//output.println("newMessage");
			objOutput.writeObject(email);
			objOutput.flush();
		}
		catch (IOException e)
		{
			JOptionPane.showMessageDialog(null, "Unable to send object");
		}
	}
	
	public void sendMessageWithAttachment()
	{
		recipient = sendMessageName.getText();
		message = sendMessage.getText();
		command = "newMessage";
		int index = 0;
		
		Email email = new Email(recipient, userName, message, "newMessageAttachment", file.getName(), file, null);  //command);
		try
		{
			//output.println("newMessage");
			objOutput.writeObject(email);
			objOutput.flush();
		}
		catch (IOException e)
		{
			JOptionPane.showMessageDialog(null, "Unable to send object");
		}
		
		sendWithAttachment = false;
	}
	
	public void login()
	{
		userName = txtUserName.getText();
		JOptionPane.showMessageDialog(null, "You are Logging in As..." + userName);
		
		try
		{
			Email email = new Email("", userName, "", "login", null, null,null);
			objOutput.writeObject(email);
			objOutput.flush();
			btnLogin.setEnabled(false);
			btnReadMailbox.setEnabled(true);
			btnLogout.setEnabled(true);
			btnAttach.setEnabled(true);
		}
		catch (IOException ioEx)
		{
			JOptionPane.showMessageDialog(null, "There is a problem logging in. Please make sure server is running");
		}		
	}
	
	public void readMailbox()
	{
		userEmail.clear(); // clears the email array ready for new emails
		command = "readMailbox";		
		Email email = new Email("", userName, "", command, null, null, null);  //command);
		try
		{
			objOutput.writeObject(email);
			objOutput.flush();
			showMailbox();
		}
		catch (IOException e)
		{
			JOptionPane.showMessageDialog(null, "Unable to send object");
		}
	}
	
	public static void showMailbox()
	{
		emailData.clear();
			try
			{	
				 Email readMailbox;// = (Email) objInput.readObject();

					do
					{
					readMailbox = (Email) objInput.readObject();
					
					if (readMailbox.getCommand().equals("NOMAIL")) // If the user has no Mail in their mailbox
					{
						emailData.addElement("No Emails in Mailbox for " + readMailbox.getRecipient());
					}
						
					if(readMailbox.getCommand().equals("newMessage")) // display messages in list if it is of type "message"
					{
						String emailMessage = "Message : " +  readMailbox.getMessage();
						String emailSender = "From : " + readMailbox.getSender();
						//String emailID = "ID : " + readMailbox.getIndex();
						String emailAttachment = "There is NO Attachment on this Email";
						emailData.addElement(emailMessage);
						emailData.addElement(emailSender);
						emailData.addElement(emailAttachment);
						//emailData.addElement(emailID);
						emailData.addElement(" ");
					}
					
					if(readMailbox.getCommand().equals("newMessageAttachment")) // If theres a message with an attachment
					{
						String emailMessage = "Message : " +  readMailbox.getMessage();
						String emailSender = "From : " + readMailbox.getSender();
						String emailID = "ID : " + readMailbox.getIndex();
						String emailAttachment = "There is an Attachment on this Email";
						File emailAttachmentFile = readMailbox.getFile();
						String location = readMailbox.getFileLocation();
						String filename = emailAttachmentFile.getName();
						userEmail.add(readMailbox); // Stores users Email into the array temporarily
						
						emailData.addElement(emailID);
						emailData.addElement(emailMessage);
						emailData.addElement(emailSender);
						emailData.addElement("Attachments : ");
						emailData.addElement(location);
						emailData.addElement("Please Click above to view attachment");

						//emailData.addElement(emailID);
						emailData.addElement(" ");

					}
					
					}while (!readMailbox.getCommand().equals("STOP"));
				
			}
			catch (IOException e)
			{
			}
			catch (ClassNotFoundException e)
			{
			}
 
	
}

	
	

	public void actionPerformed(ActionEvent e)
	{
		if (e.getSource()==btnLogin) // If the login button is clicked
		{
			login();
		}
		
		if (e.getSource()==btnSendMessage) // "If the send message button is clicked
		{
			if (sendWithAttachment == true)
			{
				sendMessageWithAttachment();
			}
			else
			{
				sendMessage();
			}
			
		}
		
		if (e.getSource()==btnAttach) // if the attach button has been clicked
		{
			int retval = fileChooser.showOpenDialog(null);
	         if (retval == JFileChooser.APPROVE_OPTION) 
	         {
	             //... The user selected a file, get it, use it.
	             file = fileChooser.getSelectedFile();
	             JOptionPane.showMessageDialog(null, "The file " + file.getName() + " has been added");
	             //file = null;
	             sendWithAttachment = true;
	         }
	         else
	         {
	         JOptionPane.showMessageDialog(null, "Attachment Cancelled");
	         }
		}
		
		if (e.getSource()==btnLogout) //If the logout button is clicked
		{
			
			try
			{
				Email email = new Email("","", "", "QUIT", null, null, null);
				objOutput.writeObject(email);
				objOutput.flush();
				socket.close();
				JOptionPane.showMessageDialog(null, "You have successfully logged out");
				btnLogin.setEnabled(true);
				emailData.clear();
				btnLogout.setEnabled(false);
			}
			catch (IOException ioEx)
			{
				JOptionPane.showMessageDialog(null, "Unable to disconnect");
			}
			
		}
		if (e.getSource()==btnReadMailbox) // If the Read Mailbox button is clicked
		{
			readMailbox();
					
		}
		
		if (e.getSource()==btnViewAttach) // If the Read Mailbox button is clicked
		{		  
			try {
				viewAttachment();
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}				
		}
		
		if (e.getSource()==btnDelete) // If the Delete button is clicked
		{
			
			
			try
			{
				String listSelected = "" + mailbox.getSelectedValue();
				//JOptionPane.showMessageDialog(null, listSelected);
				Email email = new Email("","", listSelected, "DELETE", null, null, null);  //command);
				objOutput.writeObject(email);
				objOutput.flush();
				
				
			}
			catch (IOException e1)
			{
			}

			readMailbox();

		}
		
		if (e.getSource() == play)
			clip.play();
		if (e.getSource() == stop)
			clip.stop();
		if (e.getSource() == loop)
			clip.loop();
		
		
		
	}
		
	
	
	
	public void viewAttachment() throws IOException
	{
		String listSelected = (String)mailbox.getSelectedValue();
		
		
		for (int i = 0; i < userEmail.size(); i++)
		{
			Email sendingMailbox = userEmail.get(i);
			String attachmentFile = sendingMailbox.getFileLocation();

			if (attachmentFile.equals(listSelected))
			{
				// Open the attachment Window and play file
				File attachment = sendingMailbox.getFile();
				
				
				if (attachment.getName().endsWith(".au")) // If the attachment is an Audio File
				{
				JFrame viewAttachment = new JFrame();
				viewAttachment.setTitle("View Attachment");
				viewAttachment.pack();
				viewAttachment.setSize(500,600);
				viewAttachment.setVisible(true);
				//viewAttachment.setResizable( false );		
				//viewAttachment.setDefaultCloseOperation(EXIT_ON_CLOSE);
				
				////////////////////////////////////////////
				JPanel buttonPanel;
				
				//String URL = "file:///C:/Users/Jack/workspace/NSD Phase 2/" + listSelected;
				URI uri = attachment.toURI(); // changes the attachment into a URI
				try
				{
					URL url = uri.toURL(); // changes the previous URI to URL for the audio player to use
					clip = Applet.newAudioClip(url);
				}
				catch(MalformedURLException e)
				{
					System.out.println("*** Invalid URL! ***");
				}

				play = new JButton("Play");
				play.addActionListener(this);
				stop = new JButton("Stop");
				stop.addActionListener(this);
				loop = new JButton("Loop");
				loop.addActionListener(this);

				buttonPanel = new JPanel();
				buttonPanel.add(play);
				buttonPanel.add(stop);
				buttonPanel.add(loop);

				viewAttachment.add(buttonPanel,BorderLayout.SOUTH);
				}
				
				if (attachment.getName().endsWith(".gif")) 		// If the attachment is a GIF
				{
					BufferedImage image;
					
					JFrame viewAttachment = new JFrame();
					viewAttachment.setTitle("View Attachment");
					viewAttachment.pack();
					viewAttachment.setSize(500,600);
					viewAttachment.setVisible(true);
					
					image = ImageIO.read(attachment);

					
					JLabel attachmentImage = new JLabel(new ImageIcon(image));
					viewAttachment.add(attachmentImage);
					
				}
				
				if (attachment.getName().endsWith(".mpeg")) 		// If the attachment is a Video
				{
					try
					{
			 			createPlayer(attachment);
					}
					catch (Exception otherEx)
					{
			         	JOptionPane.showMessageDialog(this,
			            	"Unable to load file!", "Invalid file type",
			           		 JOptionPane.ERROR_MESSAGE );
					}
			}

		}
		}
		

		
	}
	
   	private void createPlayer(File attachment) throws Exception
   	{
		URI uri = attachment.toURI();
		player = Manager.createPlayer(uri.toURL());

		player.addControllerListener(this);
		player.start();
	}
	
	
	public void controllerUpdate(ControllerEvent e)
	{
		
		JFrame viewAttachment = new JFrame();
		
		Container pane = viewAttachment.getContentPane(); //Note!!!
		
       	if (e instanceof RealizeCompleteEvent)
		{
			Component visualComponent =
               			player.getVisualComponent();

     		if (visualComponent != null)
				pane.add(visualComponent, BorderLayout.CENTER);

         	Component controlsComponent =
               	player.getControlPanelComponent();

         	if (controlsComponent != null)
				pane.add(controlsComponent, BorderLayout.SOUTH);
         	
         	
    		viewAttachment.setTitle("View Attachment");
    		viewAttachment.pack();
    		viewAttachment.setSize(500,600);
    		viewAttachment.setVisible(true);
    		//viewAttachment.add(pane);
         	pane.doLayout();
		}
		
	}
	

}



